package modelo.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import modelo.DetalleSolicitud;
import modelo.Equipo;
import modelo.Solicitud;
import modelo.Status;
import modelo.Sucursal;

/*
 * Maneja entidades:
 *   - Solicitud
 *   - Detalle de solicitud
 */

public class DAOSolicitud {
	protected HashMap<Integer, Solicitud> solicitudes = new HashMap<Integer, Solicitud>();
	protected HashMap<Integer, DetalleSolicitud> detallesSolicitud = new HashMap<Integer, DetalleSolicitud>();
	
	public void cargarSolicitudes() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM solicitud\n"
			);
		
		try {
			while (rs.next()) {
				Solicitud e = new Solicitud(rs.getInt("cod_solicitud"), rs.getString("descripcion"), Servidor.clientes().consultarSucursalPorCodigo(rs.getInt("cod_sucursal")), Status.valueOf(rs.getInt("status")));
				solicitudes.put(e.clave(), e);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public Solicitud agregarSolicitud(int codigo, String descripcion, Sucursal sucursal, Status status) {
		boolean b = Servidor.ejecutar(
			"INSERT INTO solicitud\n" +
			"    (cod_solicitud, descripcion, cod_sucursal, status)\n" +
			"VALUES\n" +
			"    (" + codigo + ", '" + descripcion + "', " + sucursal.getCodigo() + ", " + status.toInt() + ")\n"
			);
			
		if (!b) return null;
			
		Solicitud e = new Solicitud(codigo, descripcion, sucursal, status);
		solicitudes.put(e.clave(), e);
		
		return e;
	}

	/*public Solicitud agregarSolicitud(String descripcion, Sucursal sucursal, Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO solicitud\n" +
				"    (descripcion, cod_sucursal, status)\n" +
				"VALUES\n" +
				"    ('" + descripcion + "', " + sucursal.getCodigo() + ", " + status.toInt() + ")\n" +
				"RETURNING cod_solicitud"
				);
				
			if (!rs.next()) return null;
				
			Solicitud e = new Solicitud(rs.getInt("cod_solicitud"), descripcion, sucursal, status);
			solicitudes.put(e.clave(), e);
			
			return e;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}*/
	
	public int nuevoCodigoSolicitud() {
		try {
			ResultSet rs = Servidor.consultar(
					"SELECT nextval('solicitud_cod_solicitud_seq'::regclass) codigo"
					);
			if (rs.next()) return rs.getInt("codigo");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return -1;
	}
	
	public Solicitud modificarSolicitud(Solicitud solicitud) {
		boolean b = Servidor.ejecutar(
			"UPDATE solicitud\n" +
			"SET descripcion = '" + solicitud.getDescripcion() + "',\n" +
			"    cod_sucursal = " + solicitud.getSucursal().getCodigo() + ",\n" +
			"    status = " + solicitud.getStatus().toInt() + "\n" +
			"WHERE cod_solicitud = " + solicitud.getCodigo() + "\n"
			);
		
		if (!b) return null;
		
		return solicitud;
	}
	
	public ArrayList<Solicitud> consultarSolicitudes() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM solicitud\n"
			);
		
		return adjuntarSolicitud(rs);
	}
	
	public ArrayList<Solicitud> consultarSolicitudesPorStatus(Status status) {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM solicitud\n"+
			"WHERE status = " + status.toInt() + "\n"
			);
		
		return adjuntarSolicitud(rs);
	}
	
	public ArrayList<Solicitud> consultarSolicitudesPorDetallesConStatus(Status status) {
		ResultSet rs = Servidor.consultar(
			"SELECT s.cod_solicitud cod_solicitud\n" +
			"FROM solicitud s\n" +
			"INNER JOIN detalle_solicitud d ON d.cod_solicitud = s.cod_solicitud\n" +
			"WHERE d.status = " + status.toInt() + "\n" +
			"GROUP BY s.cod_solicitud"
			);
		
		return adjuntarSolicitud(rs);
	}

	public Solicitud consultarSolicitudPorCodigo(int cod) {
		return solicitudes.get(cod);
	}

	private ArrayList<Solicitud> adjuntarSolicitud(ResultSet rs) {
		ArrayList<Solicitud> lst = new ArrayList<Solicitud>();
		
		try {
			while (rs.next())
				lst.add(solicitudes.get(rs.getInt("cod_solicitud")));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return lst;
	}
	
	public void cargarDetallesSolicitud() {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM detalle_solicitud\n"
			);
		
		try {
			while (rs.next()) {
				Integer codigoEquipo = rs.getInt("cod_equipo");
				DetalleSolicitud e = new DetalleSolicitud(rs.getInt("cod_detalle"), rs.getString("descripcion"), consultarSolicitudPorCodigo(rs.getInt("cod_solicitud")), codigoEquipo == null ? null : Servidor.equipos().consultarEquipoPorCodigo(codigoEquipo), Status.valueOf(rs.getInt("status")));
				detallesSolicitud.put(e.clave(), e);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<DetalleSolicitud> consultarDetallePorSolicitud(int codigoSolicitud) {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM detalle_solicitud\n" +
			"WHERE cod_solicitud = " + codigoSolicitud + "\n"
			);
		
		return adjuntarDetallesSolicitud(rs);
	}
	
	public ArrayList<DetalleSolicitud> consultarDetallePorSolicitudYStatus(int codigoSolicitud,Status status) {
		ResultSet rs = Servidor.consultar(
			"SELECT *\n" +
			"FROM detalle_solicitud\n" +
			"WHERE cod_solicitud = " + codigoSolicitud + "\n"+
			"AND status = " + status.toInt() + "\n"
			);
		
		return adjuntarDetallesSolicitud(rs);
	}
	
	public DetalleSolicitud consultarDetalleSolicitudPorCodigo(int cod) {
		return detallesSolicitud.get(cod);
	}
	
	private ArrayList<DetalleSolicitud> adjuntarDetallesSolicitud(ResultSet rs) {
		ArrayList<DetalleSolicitud> lst = new ArrayList<DetalleSolicitud>();
		
		try {
			while (rs.next())
				lst.add(detallesSolicitud.get(rs.getInt("cod_detalle")));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return lst;
	}
	
	public DetalleSolicitud agregarDetalleSolicitud(String descripcion, Solicitud solicitud, Equipo equipo, Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO detalle_solicitud\n" +
				"    (descripcion, cod_solicitud, cod_equipo, status)\n" +
				"VALUES\n" +
				"    ('" + descripcion + "', " + solicitud.getCodigo() + ", " + equipo.getCodigo() + ", " + status.toInt() + ")\n" +
				"RETURNING cod_detalle"
				);
				
			if (!rs.next()) return null;
				
			DetalleSolicitud e = new DetalleSolicitud(rs.getInt("cod_detalle"), descripcion, solicitud, equipo, status);
			detallesSolicitud.put(e.clave(), e);
			
			return e;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public DetalleSolicitud agregarDetalleSolicitudSinEquipo(String descripcion, Solicitud solicitud,Status status) {
		try {
			ResultSet rs = Servidor.consultar(
				"INSERT INTO detalle_solicitud\n" +
				"    (descripcion, cod_solicitud, status)\n" +
				"VALUES\n" +
				"    ('" + descripcion + "', " + solicitud.getCodigo() + ", " + status.toInt() + ")\n" +
				"RETURNING cod_detalle"
				);
				
			if (!rs.next()) return null;
				
			DetalleSolicitud e = new DetalleSolicitud(rs.getInt("cod_detalle"), descripcion, solicitud, null, status);
			detallesSolicitud.put(e.clave(), e);
			
			return e;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public DetalleSolicitud modificarDetalleSolicitud(DetalleSolicitud detalleSolicitud) {
		boolean b = Servidor.ejecutar(
			"UPDATE detalle_solicitud\n" +
			"SET descripcion = '" + detalleSolicitud.getDescripcion() + "',\n" +
			"    cod_solicitud = " + detalleSolicitud.getSolicitud().getCodigo() + ",\n" +
			"    cod_equipo = " + detalleSolicitud.getEquipo().getCodigo() + ",\n" +
			"    status = " + detalleSolicitud.getStatus().toInt() + "\n" +
			"WHERE cod_detalle = " + detalleSolicitud.getCodigo() + "\n"
			);
		
		if (!b) return null;
		
		return detalleSolicitud;
	}
}
